using System.Globalization;

namespace AnalyStock.GrapImage;

internal static class CommChartMethod
{
    /// <summary>
    ///     通用Canvas面板设置Chart元素属性基本静态方法，用链式结构的书写代码
    /// </summary>
    /// <param name="element"></param>
    /// <param name="Top"></param>
    /// <param name="position"></param>
    /// <param name="canvas"></param>
    public static UIElement SetPostion(this UIElement element, double top, double left)
    {
        ArgumentNullException.ThrowIfNull(element);
        //Canvas.SetTop(element, top);    //Canvas.SetLeft(element, left);
        element.SetValue(Canvas.TopProperty, top);
        element.SetValue(Canvas.LeftProperty, left);
        return element;
    }

    public static void WithPanel(this UIElement element, Panel panel)
    {
        panel.Children.Add(element);
    }

    public static Style SetElementStyle(string styleName)
    {
        return Application.Current.Resources[styleName] as Style;
        //Application.Current.FindResource();
    }

    /// <summary>
    ///     #FFFFFF 颜色的通用字符串,转为画笔
    /// </summary>
    /// <param name="strColor"></param>
    /// <returns></returns>
    public static SolidColorBrush ConvertoBrush(this string strColor)
    {
        if (strColor.Length < 7)
        {
            return default;
        }

        return new SolidColorBrush(
            Color.FromRgb(
                byte.Parse(strColor[1..3], NumberStyles.HexNumber),
                byte.Parse(strColor[3..5], NumberStyles.HexNumber),
                byte.Parse(strColor[5..7], NumberStyles.HexNumber)
            ));
    }

    /// <summary>
    ///     #FFFFFF 颜色的通用字符串,转为色彩
    /// </summary>
    /// <param name="strColor"></param>
    /// <returns></returns>
    public static Color ConvertoColor(this string strColor)
    {
        if (strColor.Length < 7)
        {
            return default;
        }

        return Color.FromRgb(
            byte.Parse(strColor[1..3], NumberStyles.HexNumber),
            byte.Parse(strColor[3..5], NumberStyles.HexNumber),
            byte.Parse(strColor[5..7], NumberStyles.HexNumber)
        );
    }

    // Create a vertical linear gradient with one stops.    
    /// <summary>
    ///     生成一个线性垂直纯色到透明的过渡色条刷
    /// </summary>
    /// <param name="iniColor"></param>
    /// <returns></returns>
    public static LinearGradientBrush ConvertoGradientBrush(this Color iniColor)
    {
        var lineGradient = new LinearGradientBrush
        {
            StartPoint = new Point(0.5, 0),
            EndPoint = new Point(0.5, 1.0)
        };
        lineGradient.GradientStops.Add(
            new GradientStop(iniColor, 0));
        lineGradient.GradientStops.Add(
            new GradientStop(Colors.Transparent, 1));
        return lineGradient;
    }

    /// <summary>
    ///     画曲线，同时下方附带从透明到纯色的线性渐变带
    /// </summary>
    /// <param name="points"></param>
    /// <param name="canvas"></param>
    /// <param name="fillColor"></param>
    /// <param name="strokeThickness"></param>
    public static void PolylineWithGop(this PointCollection points, Canvas canvas, ShapeParam shape)
    {
        if (points.Count == 0)
        {
            return;
        }

        if (shape.IsOnlyPolygop)
        {
            PolygonOnPoints();
            return;
        }

        if (shape.IsOnlyPolyline)
        {
            PolylineOnPoints();
            return;
        }

        PolylineOnPoints();
        PolygonOnPoints();
        return;
        //画主线条
        void PolylineOnPoints()
        {
            new Polyline
            {
                StrokeThickness = shape.StrokeThickness,
                Stroke = new SolidColorBrush(shape.FillColor),
                StrokeDashArray = shape.StrokeDashArray,
                Opacity = shape.Line_Opactiy,
                Points = new PointCollection(points)
            }.WithPanel(canvas);
        };
        //画渐变颜色带
        void PolygonOnPoints()
        {
            var start_y = shape.IsXaxisOnHalfHeight ? canvas.ActualHeight / 2.0 : canvas.ActualHeight;
            //增加点，形成渐变图的闭环
            points.Add(new Point(points.Last().X, start_y));
            points.Add(new Point(points.First().X, start_y));
            new Polygon
            {
                Fill = shape.FillColor.ConvertoGradientBrush(),
                Opacity = shape.Gop_Opacity,
                Points = points
            }.WithPanel(canvas);
        }
    }

    /// <summary>
    ///     画曲线，同时下方附带一个纯色的颜色带
    /// </summary>
    /// <param name="points"></param>
    /// <param name="canvas"></param>
    /// <param name="shape"></param>
    public static void PolyColorTape(this (PointCollection up, PointCollection under) points, Canvas canvas,
        ShapeParam shape)
    {
        if (points.up.Count == 0 || points.under.Count == 0)
        {
            return;
        }

        if (shape.IsOnlyPolygop)
        {
            PolygonOnMergPoints();
            return;
        }

        if (shape.IsOnlyPolyline)
        {
            PolylineOnTwoPoints();
            return;
        }

        PolygonOnMergPoints();
        PolylineOnTwoPoints();
        return;
        //画曲线
        void PolylineOnTwoPoints()
        {
            new Polyline
            {
                StrokeThickness = shape.StrokeThickness,
                Stroke = new SolidColorBrush(shape.FillColor),
                StrokeDashArray = shape.StrokeDashArray,
                Opacity = shape.Line_Opactiy,
                Points = points.up
            }.WithPanel(canvas);
            new Polyline
            {
                StrokeThickness = shape.StrokeThickness,
                Stroke = new SolidColorBrush(shape.FillColor),
                StrokeDashArray = shape.StrokeDashArray,
                Opacity = shape.Line_Opactiy,
                Points = points.under
            }.WithPanel(canvas);
        }
        //换纯色颜色带
        void PolygonOnMergPoints() //合并
        {
            new Polygon
            {
                Fill = new SolidColorBrush(shape.FillColor),
                Opacity = shape.Gop_Opacity,
                Points = new PointCollection(points.up.Union(points.under.Reverse()))
            }.WithPanel(canvas);
        }
    }
    /// <summary>
    /// 画线的参数，以定义画曲线，还是曲线带颜色带
    /// </summary>
    public struct ShapeParam
    {
        public Color FillColor;
        public double Gop_Opacity = 0.5;
        public double Line_Opactiy = 0.8;
        public double StrokeThickness = 1.0;
        public DoubleCollection StrokeDashArray = default;
        public bool IsOnlyPolyline = false; //只画曲线
        public bool IsOnlyPolygop = false; //只画填充区
        public bool IsXaxisOnHalfHeight = false; //X轴是否中间,如MACD指标线0轴
        public ShapeParam() { }
        public ShapeParam(Color fillcolor) //默认只画线
        {
            FillColor = fillcolor;
            IsOnlyPolyline = true;
        }
    }
}